package xyz.xtt.user.controller;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.google.common.primitives.Longs;
import com.tongtong.middleware.client.MiddlewareClient;
import com.tongtong.middleware.vo.params.SendVerifyParams;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.json.JSONUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import xyz.xtt.common.response.ApiResult;
import xyz.xtt.user.constants.ErrorMessage;
import xyz.xtt.user.entity.TblUser;
import xyz.xtt.user.exception.ChainException;
import xyz.xtt.user.service.ITblUserService;
import xyz.xtt.user.utils.AssertUtils;
import xyz.xtt.user.utils.MyAESUtil;

@Slf4j
@Schema(name = "基于阿里云服务进行实人认证", description = "基于阿里云服务进行实人认证")
@RequestMapping("/api/nft/user")
@RefreshScope
@RestController
public class AuthController {
	@Autowired
	MiddlewareClient middlewareClient;
	@Autowired
	StringRedisTemplate stringRedisTemplate;
	@Autowired
	private ITblUserService iTblUserService;
	@Value("${auth.user.expirationSeconds}")
	private long expirationSeconds;

	@Operation(summary = "提交实人认证信息", description = "提交信息到阿里云进行实人认证")
	@PostMapping("/sendAuthInfo")
	public ApiResult<?> sendAuthInfo(@RequestBody SendVerifyParams params, HttpServletRequest req) throws Exception {
		String uid = req.getHeader("uid");
		log.info("/api/exchange/sendAuthInfo uid:{} body:{}", uid, JSONUtil.toJsonStr(params));
		// 验证身份证是否符合规范
		String certNo = params.getCertNo();
		if (!IdcardUtil.isValidCard(certNo)) {
			throw new ChainException(ErrorMessage.CERT_NO_ERR);
		}
		// 验证姓名是否符合规范
		if (!Validator.isChinese(params.getCertName())) {
			throw new ChainException(ErrorMessage.CERT_NAME_ERR);
		}
		int ageByIdCard = IdcardUtil.getAgeByIdCard(certNo);
		AssertUtils.isTrue(ageByIdCard < 18, ErrorMessage.CERT_LIMIT);
		// 先查询该用户认证时间是否在冷却期间
		if ("1".equals(stringRedisTemplate.opsForValue().get("auth:" + uid))) {
			throw new ChainException(ErrorMessage.CERT_LIMIT);
		}
		// 重置用户认证冷却时间
		stringRedisTemplate.opsForValue().set("auth:" + uid, "1");
		stringRedisTemplate.expire("auth:" + uid, expirationSeconds, TimeUnit.SECONDS);
		TblUser info = iTblUserService.info(Longs.tryParse(uid));
		// 查询用户是否认证过，如果没有则加入数据库
		if (info.getAuthStatus() == 0) {
//			iTblUserService.updateAuthByAppUserId(uid, params.getCertName(), params.getCertNo());
			iTblUserService.updateAuthByAppUserId(uid, params.getCertName(), MyAESUtil.encrypt(certNo));
		}
		// 发起认证请求
		params.setAppUid(uid);
		ApiResult<?> res = middlewareClient.sendVerifyRequest(params);
		return ApiResult.ok(res.getData());
	}

	@Operation(summary = "查询实人认证结果", description = "查询实人认证结果")
	@GetMapping("/receiveVerifyResult")
	public ApiResult<?> receiveVerifyResult(@RequestParam("certifyId") String certifyId, HttpServletRequest req) throws Exception {
		String uid = req.getHeader("uid");
		log.info("receiveVerifyResult param uid: {}, certifyId:{}", uid, certifyId);
		ApiResult<String> res = middlewareClient.receiveVerifyRequest(certifyId);
		log.info("receiveVerifyResult response: {}", JSONUtil.toJsonStr(res));
		// 查询认证结果，如果成功且之前状态为0则更新认证状态
		if (res.getData().equals("true")) {
			TblUser tblUser = iTblUserService.info(Longs.tryParse(uid));
			String cardNo = MyAESUtil.decrypt(tblUser.getIdCardNo());
			if (cardNo.length() == 18) {
				iTblUserService.updateAuthStatusByAppUserId(uid);
			}
		}

		return ApiResult.ok(res.getData());
	}

	@Operation(summary = "查询认证信息", description = "查询认证信息")
	@GetMapping("/getAuthInfo")
	public ApiResult<?> getAuthInfo(HttpServletRequest req) throws Exception {
		String uid = req.getHeader("uid");
		log.info("receiveVerifyResult param uid: {}", uid);
		TblUser tblUser = iTblUserService.info(Longs.tryParse(uid));
		Map<String, String> map = new HashMap<>();
		if (tblUser != null) {
			map.put("userName", tblUser.getUserName());
			map.put("idCardNo", MyAESUtil.decrypt(tblUser.getIdCardNo()));
		}
		return ApiResult.ok(map);
	}

	// 获取用户引导状态
	@GetMapping("/get_user_guide")
	public ApiResult<Integer> getUserGuide(@RequestHeader("uid") String uid) {
		// TblUser infoWithUserIdCache(Long userId);
		Long id = Long.valueOf(uid);
		TblUser tblUser = iTblUserService.info(Longs.tryParse(uid));
		Integer guide = Objects.isNull(tblUser.getGuide()) ? 0 : tblUser.getGuide();
		return ApiResult.ok(guide);
	}

	@GetMapping("/set_user_guide")
	public ApiResult<Boolean> setUserGuide(@RequestHeader("uid") String uid) {
		Long id = Long.valueOf(uid);
		return ApiResult.ok(iTblUserService.setUserGuide(id));
	}
}
